package com.example.llm.sgg.sgglangchain.tools;

import com.example.llm.sgg.sgglangchain.po.AppointmentPO;
import com.example.llm.sgg.sgglangchain.service.AppointmentService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Component
@Slf4j
public class AppointmentTools {

    @Autowired
    private AppointmentService appointmentService;

    @Autowired
    private ObjectMapper objectMapper;

    @Tool(name = "预约挂号", value = "先执行工具方法查询是否有号源，并直接给用户回答是否可预约；如果可以预约，让用户确认所有预约信息，用户确认后再进行预约挂号。")
    public String bookAppointment(AppointmentPO appointment) throws JsonProcessingException {
        log.info("bookAppointment => {}", objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(appointment));
        //查找数据库中是否包含对应的预约记录
        AppointmentPO appointmentDB = appointmentService.findOne(appointment);
        if (Objects.isNull(appointmentDB)) {
            // TODO 此处还有另一种解决方法：入参 AppointmentPO appointment 使用单独的类，避免存在模型不认识非业务字段
            appointment.setId(null); //防止大模型幻觉设置了id
            if (appointmentService.save(appointment)) {
                return "预约成功，并返回预约详情";
            } else {
                return "预约失败";
            }
        }
        return "您在相同的科室和时间已有预约";
    }

    @Tool(name = "取消预约挂号", value = "根据参数，查询预约是否存在，如果存在则删除预约记录并返回'取消预约成功'，否则返回'取消预约失败'")
    public String cancelAppointment(AppointmentPO appointment) throws JsonProcessingException {
        log.info("cancelAppointment => {}", objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(appointment));
        AppointmentPO appointmentDB = appointmentService.findOne(appointment);

        if (Objects.nonNull(appointmentDB)) {
            // 删除预约记录
            if (appointmentService.removeById(appointmentDB.getId())) {
                return "取消预约成功";
            } else {
                return "取消预约失败";
            }
        } else {
            return "您没有预约记录，请核对预约科室和时间";
        }
    }

    @Tool(name = "查询是否有号源", value = "根据科室名称、日期、时间和医生查询是否有号源，并返回给用户")
    public boolean queryDepartment(@P(value = "科室名称") String department,
                                   @P(value = "日期") String appointmentDate,
                                   @P(value = "时间，可选值：上午、下午") String time,
                                   @P(value = "医生名称", required = false) String doctorName) {
        log.info("查询是否有号源");
        log.info("科室名称：{}", department);
        log.info("日期：{}", appointmentDate);
        log.info("时间：{}", time);
        log.info("医生名称：{}", doctorName);

        // 实际业务逻辑应在此处实现
        // return true/false 表示是否有号源

        return true;
    }

}
